#pragma once

#include "KNode.h"




class KDTree
{
public:
	KDTree(void);
	~KDTree(void);
	void print(); 

	//properties
	int	 dimension;		//dimension of input data
	double_range_t* ranges; 

	int		knownMinPoints;		//minimum number of points in a cell to make it known
	double	knownMaxLength;		//minimum length of each side of known cells (if bigger, it becomes unknown)
	double	maxAllowedError;	//minimum allowed error when adding a point to a known cell
	int		maxNumberOfSamples;	//maximum number of allowed samples in each cell (used with splitCriterion=SPLIT_USE_MAX_SAMPLES)
	KNode*	root;				//access to the root of the tree
	int		totalNodes;			//total number of nodes in this tree
	double eta; 
	double getKnownness(Observation st); 

	int		splitCriterion;		//how do we decide to split a node (max number of samples, max allowed error)
	static const int SPLIT_USE_MAX_SAMPLES=1; 
	static const int SPLIT_USE_MAX_ALLOWED_ERROR=2; 
	static const int GENERALIZER_USE_MEAN=1; 
	static const int GENERALIZER_USE_LINEAR=2; 

	void setSplitCriterion(int v);
	int		generalizerType;	//what kind of local generalizer is used for each cell 

	bool  predict(Observation, double& d); //returns true if it successfully predicted it, otherwise false

	void resetPoints(); 

	//public methods
	void addPoint(Observation pt, double target);
	void addPoints(list<KData>& l); 

	void setDimensionParameters(int dim, double_range_t* r);

};
